package com.itheima.project.face.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.project.basic.ResponseWrap;
import com.itheima.project.constant.security.CustomerCacheConstant;
import com.itheima.project.core.enums.security.CustomerEnum;
import com.itheima.project.exception.ProjectException;
import com.itheima.project.face.CustomerFace;
import com.itheima.project.feign.FileFeign;
import com.itheima.project.pojo.Customer;
import com.itheima.project.pojo.Role;
import com.itheima.project.service.ICustomerAdapterService;
import com.itheima.project.service.ICustomerService;
import com.itheima.project.utils.BeanConv;
import com.itheima.project.utils.EmptyUtil;
import com.itheima.project.utils.ExceptionsUtil;
import com.itheima.project.vo.file.FileVo;
import com.itheima.project.vo.security.CustomerVo;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName CustomerFaceImpl.java
 * @Description 账户Face接口实现
 */
@Slf4j
@Component
public class CustomerFaceImpl implements CustomerFace {

    @Autowired
    BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    ICustomerService customerService;

    @Autowired
    ICustomerAdapterService customerAdapterService;

    @Autowired
    FileFeign fileFeign;

    @Override
    @Cacheable(value = CustomerCacheConstant.PAGE,key ="#pageNum+'-'+#pageSize+'-'+#customerVo.hashCode()")
    public Page<CustomerVo> findCustomerVoPage(CustomerVo customerVo,
                                               int pageNum,
                                               int pageSize)throws ProjectException {
        try {
            Page<Customer> page = customerService.findCustomerVoPage(customerVo, pageNum, pageSize);
            Page<CustomerVo> pageVo = BeanConv.toPage(page,CustomerVo.class);
            //结果集转换
            List<CustomerVo> customerVoList = pageVo.getRecords();
            if (!EmptyUtil.isNullOrEmpty(customerVoList)){
                customerVoList.forEach(n->{
                    //处理图片
                    ResponseWrap<List<FileVo>> responseWrap = fileFeign.findFileVoByBusinessId(FileVo.builder().businessId(n.getId()).build());
                    if (!EmptyUtil.isNullOrEmpty(responseWrap.getDatas())){
                        n.setFileVo(responseWrap.getDatas().get(0));
                    }else {
                        n.setFileVo(new FileVo());
                    }
                    //处理角色
                    List<Role> roles = customerAdapterService.findRoleByCustomerId(n.getId());
                    List<String> roleIdList = new ArrayList<>();
                    for (Role role : roles) {
                        roleIdList.add(String.valueOf(role.getId()));
                    }
                    String[] roleIds = new String[roleIdList.size()];
                    roleIdList.toArray(roleIds);
                    n.setHasRoleIds(roleIds);
                });
            }
            return pageVo;
        } catch (Exception e) {
            log.error("查询客户列表异常：{}", ExceptionsUtil.getStackTraceAsString(e));
            throw new ProjectException(CustomerEnum.PAGE_FAIL);
        }
    }

    @Override
    @Caching(evict = {@CacheEvict(value = CustomerCacheConstant.PAGE,allEntries = true),
        @CacheEvict(value = CustomerCacheConstant.LIST,allEntries = true),
        @CacheEvict(value = CustomerCacheConstant.USERNAME,key = "#customerVo.username"),
        @CacheEvict(value = CustomerCacheConstant.MOBILE,key = "#customerVo.mobile"),
//        @CacheEvict(value = CustomerCacheConstant.WECHAT,key = "#customerVo.openId")
    },
        put={@CachePut(value = CustomerCacheConstant.BASIC,key = "#result.id")})
    @GlobalTransactional
    public CustomerVo createCustomer(CustomerVo customerVo)throws ProjectException {
        try {
            String plainPassword = customerVo.getPassword();
            //必须要加{bcrypt}要不认证不通过
            String password = bCryptPasswordEncoder.encode(plainPassword);
            customerVo.setPassword(password);
            CustomerVo customerVoResult = BeanConv.toBean(customerService.createCustomer(customerVo), CustomerVo.class);
            //绑定附件
            if (!EmptyUtil.isNullOrEmpty(customerVoResult)&&!EmptyUtil.isNullOrEmpty(customerVo.getFileVo())){
                fileFeign.bindBusinessId(FileVo.builder()
                    .businessId(customerVoResult.getId())
                    .id(customerVo.getFileVo().getId()).build());
                customerVoResult.setFileVo(FileVo.builder()
                    .pathUrl(customerVo.getFileVo().getPathUrl())
                    .businessId(customerVoResult.getId())
                    .id(customerVo.getFileVo().getId()).build());
            }
            //处理角色
            customerVoResult.setHasRoleIds(customerVo.getHasRoleIds());
            return customerVoResult;
        } catch (Exception e) {
            log.error("保存客户异常：{}", ExceptionsUtil.getStackTraceAsString(e));
            throw new ProjectException(CustomerEnum.CREATE_FAIL);
        }

    }

    @Override
    @Caching(evict = {@CacheEvict(value = CustomerCacheConstant.PAGE,allEntries = true),
        @CacheEvict(value = CustomerCacheConstant.LIST,allEntries = true),
        @CacheEvict(value = CustomerCacheConstant.USERNAME,key = "#customerVo.username"),
        @CacheEvict(value = CustomerCacheConstant.MOBILE,key = "#customerVo.mobile"),
//        @CacheEvict(value = CustomerCacheConstant.WECHAT,key = "#customerVo.openId"),
        @CacheEvict(value = CustomerCacheConstant.ROLES,key = "#customerVo.id"),
        @CacheEvict(value = CustomerCacheConstant.RESOURCES,key = "#customerVo.id"),
        @CacheEvict(value = CustomerCacheConstant.BASIC,key = "#customerVo.id")})
    @GlobalTransactional
    public CustomerVo updateCustomer(CustomerVo customerVo)throws ProjectException {
        try {
            Boolean flag = customerService.updateCustomer(customerVo);
            if (flag){
                //移除业务原图片，并绑定新的图片到业务上
                fileFeign.replaceBindBusinessId(FileVo.builder()
                        .businessId(customerVo.getId())
                        .id(customerVo.getFileVo().getId())
                        .build());
                return customerVo;
            }else {
                log.error("修改客户异常！");
                throw new ProjectException(CustomerEnum.UPDATE_FAIL);
            }
        } catch (Exception e) {
            log.error("修改客户异常：{}", ExceptionsUtil.getStackTraceAsString(e));
            throw new ProjectException(CustomerEnum.UPDATE_FAIL);
        }
    }

    @Override
    @Caching(evict = {@CacheEvict(value = CustomerCacheConstant.PAGE,allEntries = true),
        @CacheEvict(value = CustomerCacheConstant.LIST,allEntries = true),
        @CacheEvict(value = CustomerCacheConstant.USERNAME,allEntries = true),
        @CacheEvict(value = CustomerCacheConstant.MOBILE,allEntries = true),
        @CacheEvict(value = CustomerCacheConstant.WECHAT,allEntries = true),
        @CacheEvict(value = CustomerCacheConstant.ROLES,allEntries = true),
        @CacheEvict(value = CustomerCacheConstant.RESOURCES,allEntries = true)})
    @GlobalTransactional
    public Boolean deleteCustomer(String[] checkedIds)throws ProjectException {
        try {
            Boolean flag = customerService.deleteCustomer(checkedIds);
            if (flag){
                //删除图片
                for (String checkedId : checkedIds) {
                    fileFeign.deleteFileVoByBusinessId(FileVo.builder().businessId(Long.valueOf(checkedId)).build());
                }
            }
            return flag;
        } catch (Exception e) {
            log.error("删除客户异常：{}", ExceptionsUtil.getStackTraceAsString(e));
            throw new ProjectException(CustomerEnum.DELETE_FAIL);
        }

    }

    @Override
    @Cacheable(value = CustomerCacheConstant.BASIC,key = "#customerId")
    public CustomerVo findCustomerByCustomerId(Long customerId)throws ProjectException {
        try {
            Customer user = customerService.getById(customerId);
            if (!EmptyUtil.isNullOrEmpty(user)){
                return BeanConv.toBean(user,CustomerVo.class);
            }
            return null;
        } catch (Exception e) {
            log.error("查找客户所有角色异常：{}", ExceptionsUtil.getStackTraceAsString(e));
            throw new ProjectException(CustomerEnum.SELECT_USER_FAIL);
        }
    }

    @Override
    @Cacheable(value = CustomerCacheConstant.LIST)
    public List<CustomerVo> findCustomerVoList()throws ProjectException {
        try {
            return BeanConv.toBeanList(customerService.findCustomerVoList(),CustomerVo.class);
        } catch (Exception e) {
            log.error("查找客户list异常：{}", ExceptionsUtil.getStackTraceAsString(e));
            throw new ProjectException(CustomerEnum.SELECT_USER_LIST_FAIL);
        }
    }

}
